package org.bsc.mgwt.client.widget;

import java.util.List;

import org.bsc.mgwt.client.widget.base.HasMenuItems;
import org.bsc.mgwt.client.widget.base.MMenuItem;

import com.google.gwt.core.client.GWT;
import com.google.gwt.place.shared.Place;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.googlecode.mgwt.ui.client.theme.base.ListCss;
import com.googlecode.mgwt.ui.client.widget.CellList;
import com.googlecode.mgwt.ui.client.widget.celllist.Cell;
import com.googlecode.mgwt.ui.client.widget.celllist.CellSelectedEvent;
import com.googlecode.mgwt.ui.client.widget.celllist.CellSelectedHandler;

/**
 * 
 * @author bsorrentino
 *
 */
public abstract class MMenu extends CellList<MMenuItem> implements HasMenuItems {

	static public class MenuCell implements Cell<MMenuItem> {

		
		private static Template TEMPLATE = GWT.create(Template.class);

		public interface Template extends SafeHtmlTemplates {
			@SafeHtmlTemplates.Template("<div class=\"{0}\">{1}</div>")
			SafeHtml content(String classes, String cellContents);

		}

		@Override
		public void render(SafeHtmlBuilder safeHtmlBuilder, MMenuItem model) {
			safeHtmlBuilder.append( TEMPLATE.content(model.getStyleName(), model.getText()));
			
		}

		@Override
		public boolean canBeSelected( MMenuItem model) {
			return model.isSelectable();
		}

	}

	final CellSelectedHandler handler = new CellSelectedHandler() {

		@Override
		public void onCellSelected(CellSelectedEvent event) {
			if( models==null ) return;
			
			MMenuItem item =  models.get(event.getIndex());
			
			goTo( item.getTarget() );
		}
		
	};
	
	private List<MMenuItem> models ;
	private boolean updated = true;
	
	/**
	 * 
	 */
	public MMenu() {
		super( new MenuCell() );
		
		super.addCellSelectedHandler(handler);	
	
	}

	public MMenu(Cell<MMenuItem> cell, ListCss css) {
		super(new MenuCell(), css);

		super.addCellSelectedHandler(handler);	
	}

	@Override
	public void render(List<MMenuItem> models) {
		this.models = models;
		updated = true;
		apply();
	}

	/**
	 * 
	 */
	@Override
	public final void apply() {
		if( models==null ) throw new IllegalStateException("items are not initialized yet!");
		
		if( updated ) super.render(models);
		updated = false;
	}
	
	/**
	 * <pre>
	 * 
	 * Useful method to initialize a Menu
	 * 
	 * menu
	 * 	.add( new MMenuItem("menu1") )
	 * 	.add( new MMenuItem("menu2") )
	 *  .render();
	 *  
	 * </pre>
	 * 
	 * @param item
	 * @return
	 */
	@Override
	public HasMenuItems add( MMenuItem item ) {
		
		if( models==null ) models = new java.util.ArrayList<MMenuItem>();
		
		updated = true;
		models.add( item );
		
		return this;
	}
	
	public abstract void goTo( Place place );

}
